//===============================================================================
// Microsoft Architecture Strategy Team
// LitwareHR - SaaS Sample Application
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using LitwareHR.Recruiting.Contract;
using System.Globalization;

namespace LitwareHR.Recruiting.DataModel.Sitka
{
    public static class SitkaQueryBuilder
    {
        private const string PropertyFilterSitkaQuery = @" e[""{0}""]{1}{2} ";

        public static string GetSitkaQuery(PropertyFilter[] filters, string kind)
        {
            StringBuilder where = new StringBuilder();
            where.AppendFormat(CultureInfo.InvariantCulture, @"where e.Kind==""{0}""", kind);
            if (filters.Length > 0)
            {
                where.Append(" && ");
                where.Append(GetSitkaFilter(filters));
            }

            return where.ToString();
        }

        private static string GetSitkaFilter(PropertyFilter[] filters)
        {
            StringBuilder sitkaFilter = new StringBuilder();
            if (filters.Length > 0)
            {
                for (int index = 0; index < filters.Length; index++)
                {
                    PropertyFilter filter = filters[index];

                    sitkaFilter.AppendFormat(CultureInfo.InvariantCulture, PropertyFilterSitkaQuery, filter.Name, OperatorsToSitkaQuery(filter.Operator), ValueToSitkaQuery(filter));

                    if (filter.SubFilters != null)
                    {
                        sitkaFilter.Append(LogicalConnectorsToSitkaQuery(filter.LogicalConnectorSubFilter));
                        sitkaFilter.AppendFormat(CultureInfo.InvariantCulture, @"({0})", GetSitkaFilter(filter.SubFilters));
                    }

                    if (index < filters.Length - 1)
                    {
                        sitkaFilter.Append(LogicalConnectorsToSitkaQuery(filter.LogicalConnector));
                    }
                }
            }
            return sitkaFilter.ToString();
        }
        
        private static string LogicalConnectorsToSitkaQuery(LogicalConnector logical)
        {
            if (logical == LogicalConnector.And)
            {
                return "&&";
            }
            else
            {
                return "||";
            }
        }

        private static string OperatorsToSitkaQuery(LogicalOperator op)
        {
            string operatorReturned = String.Empty;
            switch (op)
            {
                case LogicalOperator.Equal:
                    operatorReturned = "==";
                    break;
                case LogicalOperator.GreaterOrEqualThan:
                    operatorReturned = ">=";
                    break;
                case LogicalOperator.GreaterThan:
                    operatorReturned = ">";
                    break;
                case LogicalOperator.LessOrEqualThan:
                    operatorReturned = "<=";
                    break;
                case LogicalOperator.LessThan:
                    operatorReturned = "<";
                    break;
                case LogicalOperator.NotEqual:
                    operatorReturned = "!=";
                    break;
            }
            return operatorReturned;
        }

        private static string ValueToSitkaQuery(PropertyFilter filter)
        {
            string propertyReturned = string.Empty;
            switch (filter.PropertyType)
            {
                case PropertyType.String:
                    propertyReturned = String.Format(CultureInfo.InvariantCulture, @"""{0}""", filter.Value);
                    break;
                case PropertyType.Boolean:
                    propertyReturned = filter.Value;
                    break;
                case PropertyType.DateTime:
                    propertyReturned = String.Format(CultureInfo.InvariantCulture, @"DateTime(""{0}"")", filter.Value);
                    break;
            }
            return propertyReturned;
        }
    }
}
